package h5

import (
	. "chess_platform/internal/common"
	"fmt"
	"github.com/astaxie/beego/orm"
	"time"
)

//提现记录
func ListWithdraw(p ListParams, agentId int64, multiOrm ...orm.Ormer) ([]*WithdrawRecord, int64, error) {
	limit := (p.PageIndex - 1) * p.PageSize
	sql := fmt.Sprintf(`
		SELECT
			*
		FROM
			%v
		WHERE
			agent_id = %v
		ORDER BY
			id DESC
		LIMIT ?,?
	`, TableH5WithdrawRecord, agentId)
	o := NewOrm(multiOrm, DBChessCenter)
	var wr []*WithdrawRecord
	_, err := o.Raw(sql, limit, p.PageSize).QueryRows(&wr)
	if CheckError(err) {
		return nil, 0, err
	}
	var count int64
	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE agent_id = %v`,
		TableH5WithdrawRecord, agentId)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return nil, 0, err
	}
	return wr, count, nil
}

//新增提现记录
func NewWithdrawRecord(wr map[string]interface{}, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	values, sql := InsertSql(TableH5WithdrawRecord, wr)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

//提现费率(手续费,税)
func WithdrawRate(amount int64) (int64, int64, error) {
	sr, err := RuleByType(RuleServerRate)
	if err != nil {
		return 0, 0, err
	}
	tr, err := RuleByType(RuleTaxRate)
	if err != nil {
		return 0, 0, err
	}
	serverCharge := amount * sr.Amount / 10000 //手续费,万分比
	tax := amount * tr.Amount / 10000          //税,万分比
	return serverCharge, tax, nil
}

//根据类型查找提成规则
func RuleByType(typ int64, multiOrm ...orm.Ormer) (Rule, error) {
	var r Rule
	Key := fmt.Sprintf("%v%v", KeyRuleType, typ)
	err := GetCache(RedisCache, Key, &r)
	if err != nil { //cache doesn't exist
		sql := fmt.Sprintf(`
		SELECT * FROM %v WHERE type = ? LIMIT 1`, TableH5Rule)
		o := NewOrm(multiOrm, DBChessSysData)
		err := o.Raw(sql, typ).QueryRow(&r)
		if err != nil {
			return r, err
		}
		SetCache(RedisCache, Key, r, CacheExpire) // one day
	}
	r.Id = r.Type
	return r, nil
}

//新增代理银行卡信息
func NewAgentBank(ab map[string]interface{}, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	values, sql := InsertSql(TableH5AgentBank, ab)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

//返回银行卡信息，同时返回有无提现记录
func AgentBankById(uid int64, multiOrm ...orm.Ormer) (*AgentBank, int64, error) {
	sql := fmt.Sprintf(`
		SELECT * FROM %v WHERE uid = ? LIMIT 1`, TableH5AgentBank)
	o := NewOrm(multiOrm, DBChessCenter)
	var ab AgentBank
	err := o.Raw(sql, uid).QueryRow(&ab)
	if CheckNoExist(err) {
		return nil, 0, nil
	}

	var count int64 //有无提现记录
	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE agent_id = %v`,
		TableH5WithdrawRecord, uid)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return &ab, count, err
	}
	return &ab, count, nil
}

func UpdateAgentBank(ab map[string]interface{}, uid int64, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	condition := fmt.Sprintf(`uid = %v`, uid)
	values, sql := UpdateSql(TableH5AgentBank, ab, condition)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}

func NewCashRecord(cr map[string]interface{}, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	values, sql := InsertSql(TableH5CashRecord, cr)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

//注册成功要调用此函数,生成一
func NewCardCash(cc map[string]interface{}, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	values, sql := InsertSql(TableH5CardCash, cc)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

//更新代理的收入，amount为30加上30,为-30为减去30
func UpdateCash(amount, uid int64, isWithdraw bool, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	var sql string
	if !isWithdraw { //不是提现
		sql = fmt.Sprintf(`UPDATE %v SET amount = amount + %v WHERE uid = %v`,
			TableH5CardCash, amount, uid)
	} else { //提现
		sql = fmt.Sprintf(`UPDATE %v SET amount = amount + %v,withdraw_time = %v WHERE uid = %v`,
			TableH5CardCash, amount, time.Now().Unix(), uid)
	}
	result, err := o.Raw(sql).Exec()
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}

//更新代理的钻石，cardNum为30加上30,为-30为减去30
func UpdateCard(cardNum, uid int64, isBuy bool, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	sql := fmt.Sprintf(`UPDATE %v SET card_num = card_num + %v WHERE uid = %v`,
		TableH5CardCash, cardNum, uid)
	if isBuy { //如果说是购买钻石，则加到总购买钻石数里
		sql = fmt.Sprintf(`UPDATE %v SET card_num = card_num + %v,
			total_card_num = total_card_num + %v WHERE uid = %v`, TableH5CardCash, cardNum, cardNum, uid)
	}
	result, err := o.Raw(sql).Exec()
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}

//更新代理的钻石及收入
func UpdateCardCash(cardNum, amount, uid int64, isBuy bool, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChessCenter)
	sql := fmt.Sprintf(`UPDATE %v SET card_num = card_num + %v,amount = amount + %v WHERE uid = %v`,
		TableH5CardCash, cardNum, amount, uid)
	if isBuy { //如果说是购买钻石，则加到总购买钻石数里
		sql = fmt.Sprintf(`UPDATE %v SET card_num = card_num + %v,amount = amount + %v,
			total_card_num = total_card_num +%v WHERE uid = %v`, TableH5CardCash, cardNum, amount, cardNum, uid)
	}
	result, err := o.Raw(sql).Exec()
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}

//根据uid查询代理的钻石数和余额
func CardCashById(uid int64, multiOrm ...orm.Ormer) (CardCash, error) {
	sql := fmt.Sprintf(`SELECT * FROM %v WHERE uid = ? LIMIT 1`, TableH5CardCash)
	o := NewOrm(multiOrm, DBChessCenter)
	var cc CardCash
	err := o.Raw(sql, uid).QueryRow(&cc)
	if CheckNoExist(err) {
		return cc, nil
	}
	return cc, err
}

//统计累计收入，昨日收入，可提现
func StatAgentCash(uid int64, multiOrm ...orm.Ormer) (*StatCash, error) {
	sql := fmt.Sprintf(`
		SELECT
			IF(SUM(amount) is NULL,0,SUM(amount)) AS total_income
		FROM
			%v
		WHERE
			agent_id = %v AND type IN (%v,%v,%v,%v)
		`, TableH5CashRecord, uid, CashAutomatic, CashLevel2Open, CashLevel2Buy, CashLevel2Automatic)
	var stat StatCash
	o := NewOrm(multiOrm, DBChessCenter)
	err := o.Raw(sql).QueryRow(&stat.TotalIncome)
	if CheckError(err) {
		return nil, err
	}
	start, end := GetYesterdayTimestamp()
	sql = fmt.Sprintf(`
		SELECT
			IF(SUM(amount) is NULL,0,SUM(amount)) AS yesterday_income
		FROM
			%v
		WHERE
			agent_id = %v AND type IN (%v,%v,%v,%v) AND create_time >= %v AND create_time <= %v
		`, TableH5CashRecord, uid, CashAutomatic, CashLevel2Open, CashLevel2Buy, CashLevel2Automatic, start, end)
	err = o.Raw(sql).QueryRow(&stat.YesterdayIncome)
	if CheckError(err) {
		return nil, err
	}

	stat.Balance, err = RestCash(uid, multiOrm...)
	if CheckError(err) {
		return nil, err
	}
	return &stat, nil
}

//查询代理的可提现金额
func RestCash(uid int64, multiOrm ...orm.Ormer) (int64, error) {
	var restCash int64
	sql := fmt.Sprintf(`
		SELECT
			amount
		FROM
			%v
		WHERE
			uid = %v
	`, TableH5CardCash, uid)
	o := NewOrm(multiOrm, DBChessCenter)
	err := o.Raw(sql).QueryRow(&restCash)
	if CheckError(err) {
		return 0, err
	}
	return restCash, nil
}

//金钱流水账(按月分)
func ListMonth(p ListParams, agentId int64, multiOrm ...orm.Ormer) ([]*CashRecord, int64, error) {
	limit := (p.PageIndex - 1) * p.PageSize
	sql := fmt.Sprintf(`
		SELECT
			IF(SUM(amount) is NULL,0,SUM(amount)) AS amount,month
		FROM
			%v
		WHERE
			agent_id = %v
		GROUP BY
			month
		ORDER BY
			id DESC
		LIMIT ?,?
	`, TableH5CashRecord, agentId)
	o := NewOrm(multiOrm, DBChessCenter)
	var cr []*CashRecord
	_, err := o.Raw(sql, limit, p.PageSize).QueryRows(&cr)
	if CheckError(err) {
		return nil, 0, err
	}
	var count int64
	sql = fmt.Sprintf(`SELECT COUNT(DISTINCT month) FROM %v WHERE agent_id = %v`,
		TableH5CashRecord, agentId)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return cr, count, err
	}
	return cr, count, nil
}

//金钱流水账(每月详细帐单)
func ListDetail(p ListCashParams, agentId int64, multiOrm ...orm.Ormer) ([]*CashRecord, int64, error) {
	limit := (p.PageIndex - 1) * p.PageSize
	sql := fmt.Sprintf(`
		SELECT
			type,amount,month,create_time
		FROM
			%v
		WHERE
			agent_id = %v AND month = %v
		ORDER BY
			id DESC
		LIMIT ?,?
	`, TableH5CashRecord, agentId, p.Month)
	o := NewOrm(multiOrm, DBChessCenter)
	var cr []*CashRecord
	_, err := o.Raw(sql, limit, p.PageSize).QueryRows(&cr)
	if CheckError(err) {
		return nil, 0, err
	}
	var count int64
	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE agent_id = %v AND month = %v`,
		TableH5CashRecord, agentId, p.Month)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return cr, count, err
	}
	return cr, count, nil
}

//一级代理提成列表(首页中展示,因为二级代理产生的收益及本级玩家直充产出的收益)
func ListChildCash(p ListParams, agentId int64, multiOrm ...orm.Ormer) ([]*CashRecord, int64, error) {
	limit := (p.PageIndex - 1) * p.PageSize
	sql := fmt.Sprintf(`
		SELECT
			child_id,user_type,card_num,type,amount,create_time
		FROM
			%v
		WHERE
			agent_id = %v AND type IN (%v,%v,%v,%v)
		ORDER BY
			create_time DESC
		LIMIT ?,?
	`, TableH5CashRecord, agentId, CashAutomatic, CashLevel2Open, CashLevel2Buy, CashLevel2Automatic)
	o := NewOrm(multiOrm, DBChessCenter)
	var cr []*CashRecord
	_, err := o.Raw(sql, limit, p.PageSize).QueryRows(&cr)
	if CheckError(err) {
		return nil, 0, err
	}
	var count int64
	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE agent_id = %v AND type IN (%v,%v,%v,%v)`,
		TableH5CashRecord, agentId, CashAutomatic, CashLevel2Open, CashLevel2Buy, CashLevel2Automatic)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return nil, 0, err
	}
	return cr, count, nil
}

//二级代理提成列表(首页中展示,本级玩家直充产生的收益)
func ListLevel2Cash(p ListParams, agentId int64, multiOrm ...orm.Ormer) ([]*CashRecord, int64, error) {
	limit := (p.PageIndex - 1) * p.PageSize
	sql := fmt.Sprintf(`
		SELECT
			child_id,card_num,type,amount,create_time
		FROM
			%v
		WHERE
			agent_id = %v AND type = %v
		ORDER BY
			create_time DESC
		LIMIT ?,?
	`, TableH5CashRecord, agentId, CashAutomatic)
	o := NewOrm(multiOrm, DBChessCenter)
	var cr []*CashRecord
	_, err := o.Raw(sql, limit, p.PageSize).QueryRows(&cr)
	if CheckError(err) {
		return nil, 0, err
	}
	var count int64
	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE agent_id = %v`,
		TableH5CashRecord, agentId)
	err = o.Raw(sql).QueryRow(&count)
	if CheckError(err) {
		return nil, 0, err
	}
	return cr, count, nil
}
